package com.joysuch.wwyt.mh.service.impl;

import cn.zlg.common.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Splitter;
import com.joysuch.wwyt.common.constant.Constant;
import com.joysuch.wwyt.core.bean.SimpleIdMapping;
import com.joysuch.wwyt.core.bean.SimpleUserBean;
import com.joysuch.wwyt.core.entity.BaseUser;
import com.joysuch.wwyt.core.enums.DeleteFlag;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.service.BaseRoleDataAuthService;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.mh.bean.MhMajorHazardTaskRecordItemSearchBean;
import com.joysuch.wwyt.mh.bean.MhMajorHazardTaskRecordSearchBean;
import com.joysuch.wwyt.mh.bean.vo.MhMajorHazardTaskRecordGetVO;
import com.joysuch.wwyt.mh.bean.vo.MhMajorHazardTaskRecordItemVO;
import com.joysuch.wwyt.mh.bean.vo.MhMajorHazardTaskRecordVO;
import com.joysuch.wwyt.mh.bo.MhMajorHazardTaskAssignBO;
import com.joysuch.wwyt.mh.dto.MhMajorHazardTaskRecordDTO;
import com.joysuch.wwyt.mh.dto.MhMajorHazardTaskRecordItemDTO;
import com.joysuch.wwyt.mh.entity.*;
import com.joysuch.wwyt.mh.enums.ExceptionHandleEnum;
import com.joysuch.wwyt.mh.enums.MhMajorHazardCheckUserEnum;
import com.joysuch.wwyt.mh.enums.PlanCycleType;
import com.joysuch.wwyt.mh.enums.TaskStatus;
import com.joysuch.wwyt.mh.mapper.MhMajorHazardTaskRecordMapper;
import com.joysuch.wwyt.mh.service.*;
import com.joysuch.wwyt.workflow.entity.WorkFlowTask;
import com.joysuch.wwyt.workflow.repository.WorkFlowTaskDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zqw
 * @since 2022-05-24
 */
@Service
@Slf4j
public class MhMajorHazardTaskRecordServiceImpl extends ServiceImpl<MhMajorHazardTaskRecordMapper, MhMajorHazardTaskRecord> implements MhMajorHazardTaskRecordService {

    @Autowired
    private MhMajorHazardTaskRecordItemService mhMajorHazardTaskRecordItemService;
    @Autowired
    private BaseUserDao baseUserDao;
    @Autowired
    private MhMajorHazardTaskRecordAssignService mhMajorHazardTaskRecordAssignService;
    @Autowired
    private MhMajorHazardTaskAssignService mhMajorHazardTaskAssignService;
    @Autowired
    private MhMajorHazardTaskService mhMajorHazardTaskService;
    @Autowired
    private MhMajorHazardTaskRecordMapper mhMajorHazardTaskRecordMapper;
    @Autowired
    private BaseRoleDataAuthService dataAuthService;
    @Autowired
    private WorkFlowTaskDao workFlowTaskDao;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public MhMajorHazardTaskRecord finishTask(MhMajorHazardTaskRecordDTO recordDto) {
        if (CollectionUtils.isEmpty(recordDto.getItemDtoList())) {
            throw new IllegalArgumentException("检查项不能为空");
        }
        MhMajorHazardTask task = mhMajorHazardTaskService.getById(recordDto.getTaskId());
        if (task == null) {
            throw new IllegalArgumentException("履职任务不存在");
        }

        if (new Date().after(task.getEndTime())) {
            throw new IllegalArgumentException("当前任务已超时");
        }
        //保存记录
        recordDto.setRemark(task.getRemark());
        MhMajorHazardTaskRecord record = saveMhRecord(recordDto);
        //保存记录item
        mhMajorHazardTaskRecordItemService.batchSaveItem(record.getId(), recordDto.getItemDtoList());
        //保存本人记录Assign表
        mhMajorHazardTaskRecordAssignService.saveRecordAssign(Context.getCurrentUserId(), record.getId());
        //修该taskAssign结果
        mhMajorHazardTaskAssignService.update(new UpdateWrapper<MhMajorHazardTaskAssign>()
                .set("done_status", TaskStatus.FINISH.getStatus())
                .eq("id", recordDto.getAssignId()));
//        mhMajorHazardTaskAssignService.updateDoneStatus(Lists.newArrayList(record.getTaskId()), Context.getCurrentUserId(), TaskStatus.FINISH.getStatus());
        //修改task状态
        mhMajorHazardTaskService.updateTaskStatus(recordDto.getTaskId());
        return record;
    }

    @Override
    public List<MhMajorHazardTaskRecord> batchSaveAllOverdueRecords(List<MhMajorHazardTask> tasks, Date date) {
        List<MhMajorHazardTaskRecord> records = new ArrayList<>(tasks.size());
        tasks.forEach(task -> {
            MhMajorHazardTaskRecord record = new MhMajorHazardTaskRecord();
            record.setTaskId(task.getId());
            record.setTaskName(task.getTaskName());
            record.setDeadLineDesc(task.getDeadLineDesc());
            record.setCheckResult(TaskStatus.OVERDUE.getStatus());
            record.setMhId(task.getMhId());
            record.setOrgCode(task.getOrgCode());
            record.setTenentId(task.getTenentId());
            record.setDeleteFlag(DeleteFlag.EFFECTIVE.getCode());
            record.setCreateTime(date);
            record.setUpdateTime(date);
            records.add(record);
        });
        saveOrUpdateBatch(records);
        return records;
    }

    @Override
    public void batchSavePartOverdueRecords(List<MhMajorHazardTaskAssignBO> assignBoList) {
        List<MhMajorHazardTaskRecord> records = new ArrayList<>();
        List<MhMajorHazardTaskRecordAssign> assignList = new ArrayList<>();
        List<MhMajorHazardTaskRecordItem> itemList = new ArrayList<>();
        for (MhMajorHazardTaskAssignBO bo : assignBoList) {
            try {
                MhMajorHazardTaskRecord record = new MhMajorHazardTaskRecord();
                Long tenentId = bo.getTenentId();
                String orgCode = bo.getOrgCode();
                record.setTaskId(bo.getTaskId());
                record.setTaskName(bo.getTaskName());
                record.setDeadLineDesc(bo.getDeadLineDesc());
                record.setCheckResult(TaskStatus.OVERDUE.getStatus());
                record.setMhId(bo.getMhId());
                record.setOrgCode(orgCode);
                record.setTenentId(tenentId);
                record.setDeleteFlag(DeleteFlag.EFFECTIVE.getCode());
                records.add(record);
                //根据taskId 获取最近一个recordItemList
                List<MhMajorHazardTaskRecordItem> items = mhMajorHazardTaskRecordItemService.getItemsByTaskId(bo.getTaskId());
                //保存记录
                saveOrUpdate(record);
                assignList.add(convertRecordAssign(record.getId(), bo.getAssignUser(), tenentId, orgCode));
                itemList.addAll(convertRecordItem(record.getId(), items, tenentId, orgCode));
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                continue;
            }
        }
        //保存个人记录
        mhMajorHazardTaskRecordAssignService.saveOrUpdateBatch(assignList);
        //保存记录详情
        mhMajorHazardTaskRecordItemService.saveOrUpdateBatch(itemList);
    }

    private List<MhMajorHazardTaskRecordItem> convertRecordItem(Long recordId, List<MhMajorHazardTaskRecordItem> items, Long tenentId, String orgCode) {
        List<MhMajorHazardTaskRecordItem> data = new ArrayList<>();
        items.forEach(item -> {
            MhMajorHazardTaskRecordItem itemData = new MhMajorHazardTaskRecordItem();
            itemData.setRecordId(recordId);
            itemData.setCheckWay(item.getCheckWay());
            itemData.setCheckTerms(item.getCheckTerms());
            itemData.setCheckFoundation(item.getCheckFoundation());
            itemData.setAppItemName(item.getAppItemName());
            itemData.setTenentId(tenentId);
            itemData.setOrgCode(orgCode);
            itemData.setDeleteFlag(DeleteFlag.EFFECTIVE.getCode());
            data.add(itemData);
        });
        return data;
    }

    private MhMajorHazardTaskRecordAssign convertRecordAssign(Long recordId, Long assignUser, Long tenentId, String orgCode) {
        MhMajorHazardTaskRecordAssign assign = new MhMajorHazardTaskRecordAssign();
        assign.setRecordId(recordId);
        assign.setAssignUser(assignUser);
        assign.setTenentId(tenentId);
        assign.setOrgCode(orgCode);
        return assign;
    }


    MhMajorHazardTaskRecord saveMhRecord(MhMajorHazardTaskRecordDTO recordDto) {
        MhMajorHazardTaskRecord record = new MhMajorHazardTaskRecord();
        BeanUtils.copyProperties(recordDto, record);
        //完成时间
        record.setFinishDate(new Date());
        //完成情况 pc app端进来的都是已完成
        record.setCheckResult(TaskStatus.FINISH.getStatus());
        //完成状态:0异常,1正常
        int status = getRecordStatus(recordDto.getItemDtoList());
        record.setStatus(status);
        record.setExcepHandle(status);
        //签字
        String signatures = null;
        if (!CollectionUtils.isEmpty(recordDto.getSignatures())) {
            signatures = recordDto.getSignatures().stream().map(Object::toString).collect(Collectors.joining(Constant.SPLIT_COMMA));
        }
        record.setSignatures(signatures);
        saveOrUpdate(record);
        return record;
    }

    private int getRecordStatus(List<MhMajorHazardTaskRecordItemDTO> itemDtoList) {
        for (MhMajorHazardTaskRecordItemDTO dto : itemDtoList) {
            if (dto.getResult() != null && dto.getResult() == 0) {
                return 0;
            }
        }
        return 1;
    }

    @Override
    public Page<MhMajorHazardTaskRecordVO> page(MhMajorHazardTaskRecordSearchBean mhMajorHazardTaskRecordSearchBean) {
        //分页查询参数
        Page<MhMajorHazardTaskRecordVO> page = new Page<>(mhMajorHazardTaskRecordSearchBean.getPage() + 1, mhMajorHazardTaskRecordSearchBean.getSize());
        //获取当前登录人id
        Long currentUserId = Context.getCurrentUserId();
        //储存tenendId 和 orgCode
        mhMajorHazardTaskRecordSearchBean.setOrgCode(Context.getCompanyCode());
        mhMajorHazardTaskRecordSearchBean.setTenentId(Context.getCurrentTenantId());

        //通过传入的检查人员名称查询检查人员id
        List<Long> checkUserNameByIds = baseUserDao.findByNameLike(mhMajorHazardTaskRecordSearchBean.getCheckUerNames());
        if (!StringUtils.isEmpty(mhMajorHazardTaskRecordSearchBean.getCheckUerNames()) && CollectionUtils.isEmpty(checkUserNameByIds)) {
            return new Page();
        }
        mhMajorHazardTaskRecordSearchBean.setCheckUserNameList(checkUserNameByIds);
        //获取图片路径
        String imagePrefix = Constant.IMG_DOWNLOAD_URL_PREFIX;
        //获取当前用户角色拥有的部门权限
        List<Long> authDepartIds = dataAuthService.findDepartIdsByCurUser();
        Page<MhMajorHazardTaskRecordVO> taskRecordPage = mhMajorHazardTaskRecordMapper.findTaskRecordPage(page, currentUserId, authDepartIds, mhMajorHazardTaskRecordSearchBean);
        if (taskRecordPage.getRecords() != null) {
            List<Long> recordIds = taskRecordPage.getRecords().stream().map(MhMajorHazardTaskRecordVO::getId).collect(Collectors.toList());
            List<SimpleIdMapping> simpleAssigns = CollectionUtils.isNotEmpty(recordIds) ? mhMajorHazardTaskRecordMapper.findByRecordIds(recordIds) : new ArrayList<>();
            Map<Long, List<SimpleIdMapping>> recordAssignMap = simpleAssigns.stream().collect(Collectors.groupingBy(SimpleIdMapping::getSourceId));

            taskRecordPage.getRecords().forEach(e -> {
                //检查人员模糊查询
                List<SimpleIdMapping> simpleIdMappings = recordAssignMap.get(e.getId());
                List<Long> userIds = simpleIdMappings.stream().map(SimpleIdMapping::getTargetId).collect(Collectors.toList());
                List<String> realNames = baseUserDao.getRealNameByIds(userIds);
                String realNameStr = realNames.stream().collect(Collectors.joining(Constant.SPLIT_COMMA));
                //将查询出来的检查人员名称拼接
                e.setAssignName(realNameStr + "(" + MhMajorHazardCheckUserEnum.getNameByCode(e.getCheckUserType()) + ")");

                //部门数据权限
                List<Long> assignUser = Arrays.asList(e.getAssignUser().split(",")).stream().map(ed -> Long.valueOf(ed)).collect(Collectors.toList());
                //异常处理权限
                e.setCanExceptionHandle(e.getAssignUser() != null && assignUser.contains(currentUserId) && e.getCheckResult() == 1);
                //删除权限
                e.setCanDel(e.getFormulateDepartId() != null && !CollectionUtils.isEmpty(authDepartIds) && authDepartIds.contains(e.getFormulateDepartId()));

                PlanCycleType cycle = PlanCycleType.find(e.getCycleType());
                e.setCycleTypeName(null == cycle ? Constant.EMPTY_STR : cycle.getDesc());

                //MhMajorHazardTaskRecordGetVO taskRecordGetList = mhMajorHazardTaskRecordMapper.findTaskRecordGetList(e.getId());
                //封装图片
                if (!StringUtils.isEmpty(e.getSignatures())) {
                    List<String> picIds = Splitter.on(Constant.SPLIT_COMMA).trimResults().splitToList(e.getSignatures());
                    List<String> picUrls = picIds.stream().map(each -> imagePrefix + each).collect(Collectors.toList());
                    e.setSignaturesPicUrls(picUrls);
                }

                //将检查对象id和名字封装给前端
                List<SimpleUserBean> entourageIdList = new ArrayList<>();
                if (!StringUtils.isEmpty(e.getEntourageIds())) {
                    List<Long> responsibleUserIds = Arrays.asList(e.getEntourageIds().split(",")).stream().map(ed -> Long.valueOf(ed)).collect(Collectors.toList());
                    responsibleUserIds.forEach(es -> {
                        Optional<BaseUser> obu = baseUserDao.findById(es);
                        if (obu.isPresent()) {
                            SimpleUserBean selectListBean = new SimpleUserBean();
                            selectListBean.setName(obu.get().getRealName());
                            selectListBean.setId(obu.get().getId());
                            entourageIdList.add(selectListBean);
                        }
                    });
                }
                e.setEntourageIdList(entourageIdList);

                //转化数据名称给app和web端
                if (e.getCheckResult() != null) {
                    e.setCheckResultName(e.getCheckResult() == 1 ? "已完成" : "未完成(逾期未检)");
                }

                if (e.getStatus() != null) {
                    e.setStatusName(e.getStatus() == 0 ? "异常" : "正常");
                }

                if (e.getExcepHandle() != null) {
                    ExceptionHandleEnum exceptionHandle = ExceptionHandleEnum.find(e.getExcepHandle());
                    e.setExcepHandleName(null == exceptionHandle ? Constant.EMPTY_STR : exceptionHandle.getDesc());
                }

            });
        }
        return taskRecordPage;
    }


    @Override
    public MhMajorHazardTaskRecordGetVO get(Long id) {
        MhMajorHazardTaskRecordGetVO taskRecordGetList = mhMajorHazardTaskRecordMapper.findTaskRecordGetList(id);
        String imagePrefix = Constant.IMG_DOWNLOAD_URL_PREFIX;
        List<SimpleUserBean> entourageIdList = new ArrayList<>();
        //组装检查对象返回前端
        if (!StringUtils.isEmpty(taskRecordGetList.getEntourageIds())) {
            List<Long> responsibleUserIds = Arrays.asList(taskRecordGetList.getEntourageIds().split(",")).stream().map(e -> Long.valueOf(e)).collect(Collectors.toList());
            responsibleUserIds.forEach(e -> {
                Optional<BaseUser> obu = baseUserDao.findById(e);
                if (obu.isPresent()) {
                    SimpleUserBean selectListBean = new SimpleUserBean();
                    selectListBean.setName(obu.get().getRealName());
                    selectListBean.setId(obu.get().getId());
                    entourageIdList.add(selectListBean);
                }
            });
        }
        //封装图片数据
        if (!StringUtils.isEmpty(taskRecordGetList.getSignatures())) {
            List<String> picIds = Splitter.on(Constant.SPLIT_COMMA).trimResults().splitToList(taskRecordGetList.getSignatures());
            List<String> picUrls = picIds.stream().map(e -> imagePrefix + e).collect(Collectors.toList());
            taskRecordGetList.setSignaturesPicUrls(picUrls);
        }
        taskRecordGetList.setEntourageIdList(entourageIdList);
        //将检察人员id转化为名称返回给前端
        taskRecordGetList.setAssignNameRecord(MhMajorHazardCheckUserEnum.getNameByCode(taskRecordGetList.getCheckUserType()));
        taskRecordGetList.setAssignName(taskRecordGetList.getRealName() + "(" + MhMajorHazardCheckUserEnum.getNameByCode(taskRecordGetList.getCheckUserType()) + ")");
        return taskRecordGetList;
    }

    @Override
    public Page<MhMajorHazardTaskRecordItemVO> getItem(MhMajorHazardTaskRecordItemSearchBean mhMajorHazardTaskRecordItemSearchBean) {
        Page<MhMajorHazardTaskRecordItemVO> page = new Page<>(mhMajorHazardTaskRecordItemSearchBean.getPage() + 1, mhMajorHazardTaskRecordItemSearchBean.getSize());
        Page<MhMajorHazardTaskRecordItemVO> taskRecordPage = mhMajorHazardTaskRecordMapper.findTaskRecordItemList(page, mhMajorHazardTaskRecordItemSearchBean);
        // 图片固定前缀
        String imagePrefix = Constant.IMG_DOWNLOAD_URL_PREFIX;
        taskRecordPage.getRecords().forEach(each -> {
            if (!StringUtils.isEmpty(each.getPics())) {
                List<String> picIds = Splitter.on(Constant.SPLIT_COMMA).trimResults().splitToList(each.getPics());
                List<String> picUrls = picIds.stream().map(e -> imagePrefix + e).collect(Collectors.toList());
                each.setPicUrls(picUrls);
            }
            if (each.getResult() != null) {
                if (each.getResult() == 0) {
                    each.setResultName("否");
                } else if (each.getResult() == 1) {
                    each.setResultName("是");
                }
            }

            if (each.getWorkFlowTaskId() == null) {
                if (each.getResult() == null || each.getResult().intValue() == 1) {
                    each.setState("无需整改");
                } else {
                    each.setState("待整改");
                }
            } else {
                Optional<WorkFlowTask> workFlow = workFlowTaskDao.findById(each.getWorkFlowTaskId());
                if (workFlow.isPresent()) {
                    each.setState(workFlow.get().getState());
                    each.setWorkFlowTaskCode(workFlow.get().getCode());
                }
            }
            if (each.getWorkFlowTaskId() == null) {
                each.setCanState(0);
            } else {
                each.setCanState(1);
            }
        });
        return taskRecordPage;
    }


    @Override
    public void deleteById(Long id) {
        mhMajorHazardTaskRecordMapper.deleteItemById(id);
    }


}
